#include "devicegroup.h"
#include "map.h"
#include "transformable.h"

namespace VrDataCore
{
	DeviceGroup::DeviceGroup():DeviceActor()
	{
		setClassName(CLASS_DEVICE_GROUP);
	}

	DeviceGroup::~DeviceGroup()
	{}

	void DeviceGroup::addChild(CoreBase::ActorBase* mactor)
	{
		DrawableActor::addChild(mactor);
		QString id = mactor->getBindingId()==""?mactor->getId():mactor->getBindingId();
		if(!_allChild.contains(id))
		{
			_allChild.insert(id,mactor);
		}
	}

	void DeviceGroup::removeChild(CoreBase::ActorBase* mactor)
	{
		if(mactor==NULL || mactor->getDrawable()==NULL)
			return;
		if(mactor->isInstanceOf(CLASS_DEVICE_GROUP))
			dynamic_cast<DeviceGroup*>(mactor)->clearAllChildren();
		QString id = mactor->getBindingId()==""?mactor->getId():mactor->getBindingId();
		QMap<QString,CoreBase::ActorBase*>::iterator iter = _allChild.find(id);
		if(iter!=_allChild.end())
		{
			_allChild.remove(id);
		}
		DrawableActor::removeChild(mactor);
	}

	void DeviceGroup::clearAllChildren(const QString& classname,bool isinstanceof)
	{
		if(classname !="")
		{
			QMap<QString,CoreBase::ActorBase*>::Iterator iter = _allChild.begin();
			while(iter!=_allChild.end())
			{
				if(iter.value()->isInstanceOf(CLASS_DEVICE_GROUP))
				{
					dynamic_cast<DeviceGroup*>(iter.value())->clearAllChildren(classname,isinstanceof);
				}
				if(iter.value()->getClassName() == classname || isinstanceof && iter.value()->isInstanceOf(classname))
				{
					iter = _allChild.erase(iter);
				}
				else
					iter++;
			}
		}
		else
		{
			QMap<QString,CoreBase::ActorBase*>::iterator iter = _allChild.begin();
			while(iter!=_allChild.end())
			{
				if(iter.value()->isInstanceOf(CLASS_DEVICE_GROUP))
				{
					dynamic_cast<DeviceGroup*>(iter.value())->clearAllChildren("",isinstanceof);
				}
				iter = _allChild.erase(iter);
			}
		}
	}

	void DeviceGroup::addChild(QVector<CoreBase::ActorBase*> mactors)
	{
		for(int i=0;i<mactors.size();++i)
		{
			addChild(mactors.at(i));
		}
	}
	
	void DeviceGroup::removeChild(QVector<CoreBase::ActorBase*> mactors)
	{
		for(int i=0;i<mactors.size();++i)
		{
			removeChild(mactors.at(i));
		}
	}

	void DeviceGroup::getAllChildren(QList<CoreBase::ActorBase*>& returnval,const QString& classname,bool isinstanceof,bool findchild)
	{
		QMap<QString,CoreBase::ActorBase*>::iterator iter = _allChild.begin();
		for(;iter!=_allChild.end();iter++)
		{
			if(classname == "")
				returnval.push_back(iter.value());
			else
			{
				if(isinstanceof && iter.value()->isInstanceOf(classname))
				{
					returnval.push_back(iter.value());
				}
			}
			if(findchild && iter.value()->isInstanceOf("DeviceGroup"))
			{
				dynamic_cast<DeviceGroup*>(iter.value())->getAllChildren(returnval,classname,isinstanceof,findchild);
			}
		}
	}

	void DeviceGroup::onMapLoadEnd(CoreBase::Map* map)
	{
		DeviceActor::onMapLoadEnd(map);
		QMap<QString,osg::ref_ptr<CoreBase::ActorBase>> allactors = map->getAllActors();
		QMap<QString,osg::ref_ptr<CoreBase::ActorBase>>::Iterator iter = allactors.begin();
		for(;iter!=allactors.end();++iter)
		{
			if(iter.value()->isInstanceOf(CLASS_DRAWABLE))
			{
				DrawableActor* actor = dynamic_cast<DrawableActor*>(iter.value().get());
				if(actor->getParentID() == getId())
				{
					actor->onMapLoadEnd(map);
					addChild(iter.value().get());
				}
			}
		}
	}

	void DeviceGroup::getAllObjects(const QString& classname,bool isinstanceof,QVector<CoreBase::ActorBase*>& returnvector)
	{
		QMap<QString,CoreBase::ActorBase*>::iterator iter = _allChild.begin();
		for(;iter!=_allChild.end();iter++)
		{
			if(classname == "")
			{
				returnvector.push_back(iter.value());
			}
			else
			{
				if(isinstanceof && iter.value()->isInstanceOf("DeviceGroup"))
				{
					dynamic_cast<DeviceGroup*>(iter.value())->getAllObjects(classname,isinstanceof,returnvector);
				}
			}
		}
	}

	CoreBase::ActorBase* DeviceGroup::getActorById(const QString& id,const QString& classname,bool isinstanceof,bool findchild)
	{
		QMap<QString,CoreBase::ActorBase*>::iterator iter = _allChild.find(id);
		if(iter!=_allChild.end())
			return iter.value();
		CoreBase::ActorBase* rv = NULL;
		if(findchild)
		{
			iter = _allChild.begin();
			for(;iter!=_allChild.end();++iter)
			{
				if(iter.value()->isInstanceOf("DeviceGroup"))
				{
					rv = dynamic_cast<DeviceGroup*>(iter.value())->getActorById(id,classname,isinstanceof,findchild);
					if(rv!=NULL)
						return rv;
				}
			}
		}
		return NULL;
	}
}